package com.lplb.common.core.utils.auth;

import com.lplb.common.core.constant.base.BaseConstant;
import io.jsonwebtoken.*;

import java.util.Date;
import java.util.List;

/**
 *  jwt 工具类
 * @author 王松
 * @mail 1720696548@qq.com
 * @date 2020/7/5 0005 19:13
 */
public class JwtUtil {

    // 主题（随意,无实际用处）
    private static final String SUBJECT = "jwt-lplb";

    // 加密key（黑客没有该值无法篡改token内容）
    private static final String APPSECRET_KEY = "lplb1234";

    // jwt的token有效期
    private static final long YH_EXPIRATION = 1000L * 60 * 60 * 24 * 15;  // 15天 （用户端）
    private static final long PT_EXPIRATION = 1000L * 60 * 60;            // 1小时（管理端）

    //字段名
    private static final String ROLES_KEY = "roles"; //用户当前资源权限
    private static final String TYPE_KEY = "type";   //类型-管理端/用户端
    private static final String USER_KEY = "user";   //用户信息-DES对称加密数据,前端无法获取

    /**
     *  平台端生成token
     *
     * @param userJson  用户信息json (实体类所有数据)
     * @param roles  登录用户的所有接口权限url
     * @return java.lang.String
     * @date 2020/7/6 0006 9:26
     */
    public static String generateToken(String userJson, List<String> roles) {
        // 对用户信息进行DES加密
        String encryptUser = DESUtil.encrypt(userJson.getBytes(), DESUtil.DES_KEY);
        String token = Jwts
                .builder()
                // 主题
                .setSubject(SUBJECT)
                // 添加jwt自定义值, 用户当前的所有信息JSON, 用户接口权限
                .claim(USER_KEY, encryptUser)
                .claim(ROLES_KEY, roles)
                .claim(TYPE_KEY, BaseConstant.Sys.LOGIN_TYPE_PT)//表示管理端
                // jwt生成时间
                .setIssuedAt(new Date())
                // jwt过期时间
                .setExpiration(new Date(System.currentTimeMillis() + PT_EXPIRATION))
                // jwt加密方式+加密key
                .signWith(SignatureAlgorithm.HS256, APPSECRET_KEY).compact();
        //测试获取信息
//        System.out.println("用户信息获取：" + getUser(token));
//        System.out.println("权限信息获取：" + getRoles(token));
        return token;
    }


    /**
     *  用户端生成token
     *
     * @param userJson  用户信息json (实体类所有数据)
     * @return java.lang.String
     * @date 2020/7/6 0006 9:26
     */
    public static String generateToken(String userJson) {
        // 对用户信息进行DES加密
        String encryptUser = DESUtil.encrypt(userJson.getBytes(), DESUtil.DES_KEY);
        String token = Jwts
                .builder()
                // 主题
                .setSubject(SUBJECT)
                // 添加jwt自定义值, 用户当前的所有信息JSON, 用户接口权限
                .claim(USER_KEY, encryptUser)
                .claim(TYPE_KEY, BaseConstant.Sys.LOGIN_TYPE_YH)//表示用户端
                // jwt生成时间
                .setIssuedAt(new Date())
                // jwt过期时间
                .setExpiration(new Date(System.currentTimeMillis() + YH_EXPIRATION))
                // jwt加密方式+加密key
                .signWith(SignatureAlgorithm.HS256, APPSECRET_KEY).compact();
        //测试获取信息
//        System.out.println("用户信息获取：" + getUser(token));
//        System.out.println("权限信息获取：" + getRoles(token));
        return token;
    }


    /**
     * 获取用户信息 -> JSON字符串 (获取具体用户信息数据参考: JSON.parseObject(userJson, AdminUser.class).getId())
     *
     * @param token
     * @return json 获取后自行转换为对应实体类 || 或json对象获取数据
     */
    public static String getUser(String token) {
        Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
        String decryptUser = claims.get(USER_KEY).toString();
        String userJson = null;
        try {
            //对用户信息进行解密
            userJson = DESUtil.decrypt(decryptUser, DESUtil.DES_KEY);
        } catch (Exception e) {
            System.out.println("DES解密失败");
            return "error";
            //e.printStackTrace();
        }
        return userJson;
    }


    /**
     * 获取用户角色的权限列表
     *
     * @param token
     * @return 角色URL权限列表，没有返回 null
     */
    public static List<String> getRoles(String token) {
        Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
        return (List) claims.get(ROLES_KEY);
    }


    /**
     * 获取访问接口类型  type=1 管理端  ||  type=2 用户端
     *
     * @param token
     * @return 角色URL权限列表，没有返回 null
     */
    public static Integer getType(String token) {
        Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
        return (Integer) claims.get(TYPE_KEY);
    }


    /**
     * 是否过期
     *
     * @param token
     * @return 未过期 true /过期false
     */
    public static boolean isExpiration(String token) {
        Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
        // System.out.println("Token过期时间: " + claims.getExpiration());
        return claims.getExpiration().after(new Date());
    }
}